<template>
  <div style="width: 100%; height: 100%; position: relative">
    <video
      ref="videoRef"
      :src="computedSrc"
      :poster="props.poster"
      :preload="props.preload"
      :autoplay="props.autoplay"
      :loop="props.loop"
      :muted="props.muted"
      :controls="props.controls"
      :crossorigin="props.crossorigin"
      :style="getVideoStyle()"
      @loadstart="handleLoadStart"
      @loadeddata="handleLoadedData"
      @canplay="handleCanPlay"
      @play="handlePlay"
      @pause="handlePause"
      @ended="handleEnded"
      @error="handleError"
      @timeupdate="handleTimeUpdate"
      @volumechange="handleVolumeChange"
    >
      <source v-for="source in sources" :key="source.src" :src="source.src" :type="source.type" />
      您的浏览器不支持视频播放。
    </video>

    <!-- 加载状态 -->
    <div v-if="isLoading" class="video-loading" :style="getLoadingStyle()">
      <div class="loading-spinner"></div>
      <span class="loading-text">{{ props.loadingText }}</span>
    </div>

    <!-- 错误状态 -->
    <div v-if="hasError" class="video-error" :style="getErrorStyle()">
      <div class="error-icon">⚠️</div>
      <div class="error-message">{{ errorMessage }}</div>
      <button v-if="props.showRetry" class="retry-button" @click="retry">重试</button>
    </div>

    <!-- 自定义控制栏 -->
    <div
      v-if="props.customControls && !props.controls"
      class="custom-controls"
      :style="getControlsStyle()"
    >
      <button class="control-btn" @click="togglePlay">
        {{ isPlaying ? '⏸️' : '▶️' }}
      </button>
      <div class="time-display">{{ formatTime(currentTime) }} / {{ formatTime(duration) }}</div>
      <input
        type="range"
        class="progress-bar"
        :value="currentTime"
        :max="duration"
        @input="seekTo"
      />
      <button class="control-btn" @click="toggleMute">
        {{ isMuted ? '🔇' : '🔊' }}
      </button>
      <input
        type="range"
        class="volume-bar"
        :value="volume * 100"
        min="0"
        max="100"
        @input="setVolume"
      />
      <button class="control-btn" @click="toggleFullscreen">🔳</button>
    </div>

    <!-- 播放状态指示器 -->
    <div
      v-if="props.showPlayIcon && !isPlaying && !hasError && !isLoading"
      class="play-indicator"
      @click="togglePlay"
    >
      ▶️
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';

interface VideoSource {
  src: string;
  type: string;
}

const props = defineProps({
  src: {
    type: String,
    default: '',
    required: true
  },
  sources: {
    type: Array as () => VideoSource[],
    default: () => []
  },
  poster: {
    type: String,
    default: ''
  },
  preload: {
    type: String as () => 'auto' | 'metadata' | 'none',
    default: 'metadata'
  },
  autoplay: {
    type: Boolean,
    default: false
  },
  loop: {
    type: Boolean,
    default: false
  },
  muted: {
    type: Boolean,
    default: false
  },
  controls: {
    type: Boolean,
    default: true
  },
  customControls: {
    type: Boolean,
    default: false
  },
  crossorigin: {
    type: String as () => 'anonymous' | 'use-credentials',
    default: undefined
  },
  width: {
    type: [String, Number],
    default: '100%'
  },
  height: {
    type: [String, Number],
    default: '100%'
  },
  objectFit: {
    type: String as () => 'contain' | 'cover' | 'fill' | 'none' | 'scale-down',
    default: 'contain'
  },
  backgroundColor: {
    type: String,
    default: '#000000'
  },
  borderRadius: {
    type: String,
    default: '0'
  },
  loadingText: {
    type: String,
    default: '正在加载视频...'
  },
  errorText: {
    type: String,
    default: '视频加载失败'
  },
  showRetry: {
    type: Boolean,
    default: true
  },
  showPlayIcon: {
    type: Boolean,
    default: true
  },
  streamType: {
    type: String as () => 'auto' | 'hls' | 'flv' | 'rtmp' | 'webrtc',
    default: 'auto'
  },
  rtspOverHttp: {
    type: Boolean,
    default: false
  }
});

const emit = defineEmits([
  'loadstart',
  'loadeddata',
  'canplay',
  'play',
  'pause',
  'ended',
  'error',
  'timeupdate',
  'volumechange',
  'retry',
  'fullscreen'
]);

const videoRef = ref<HTMLVideoElement>();
const isLoading = ref(true);
const hasError = ref(false);
const errorMessage = ref('');
const isPlaying = ref(false);
const isMuted = ref(props.muted);
const volume = ref(1);
const currentTime = ref(0);
const duration = ref(0);
const retryCount = ref(0);

const computedSrc = computed(() => {
  // 添加时间戳防止缓存，用于重试
  if (retryCount.value > 0 && props.src) {
    const separator = props.src.includes('?') ? '&' : '?';
    return `${props.src}${separator}_t=${Date.now()}`;
  }
  return props.src;
});

const sources = computed(() => {
  if (props.sources.length > 0) {
    return props.sources;
  }
  if (props.src) {
    // 根据文件扩展名自动判断类型
    const ext = props.src.split('.').pop()?.toLowerCase();
    let type = 'video/mp4';

    switch (ext) {
      case 'mp4':
        type = 'video/mp4';
        break;
      case 'webm':
        type = 'video/webm';
        break;
      case 'ogg':
        type = 'video/ogg';
        break;
      case 'm3u8':
        type = 'application/x-mpegURL';
        break;
      case 'flv':
        type = 'video/x-flv';
        break;
    }

    return [{ src: props.src, type }];
  }
  return [];
});

const getVideoStyle = () => {
  const style: Record<string, string> = {
    width: typeof props.width === 'number' ? `${props.width}px` : props.width,
    height: typeof props.height === 'number' ? `${props.height}px` : props.height,
    objectFit: props.objectFit,
    backgroundColor: props.backgroundColor,
    borderRadius: props.borderRadius.includes('px')
      ? props.borderRadius
      : `${props.borderRadius}px`,
    display: isLoading.value || hasError.value ? 'none' : 'block'
  };

  return style;
};

const getLoadingStyle = () => {
  return {
    position: 'absolute' as const,
    top: '0',
    left: '0',
    width: '100%',
    height: '100%',
    display: 'flex',
    flexDirection: 'column' as const,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: props.backgroundColor,
    zIndex: '10'
  };
};

const getErrorStyle = () => {
  return {
    position: 'absolute' as const,
    top: '0',
    left: '0',
    width: '100%',
    height: '100%',
    display: 'flex',
    flexDirection: 'column' as const,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: props.backgroundColor,
    zIndex: '10',
    color: '#666',
    textAlign: 'center' as const,
    padding: '20px'
  };
};

const getControlsStyle = () => {
  return {
    position: 'absolute' as const,
    bottom: '0',
    left: '0',
    right: '0',
    background: 'linear-gradient(transparent, rgba(0,0,0,0.7))',
    padding: '10px',
    display: 'flex',
    alignItems: 'center',
    gap: '10px'
  };
};

// 事件处理函数
const handleLoadStart = (event: Event) => {
  isLoading.value = true;
  hasError.value = false;
  emit('loadstart', event);
};

const handleLoadedData = (event: Event) => {
  isLoading.value = false;
  if (videoRef.value) {
    duration.value = videoRef.value.duration;
  }
  emit('loadeddata', event);
};

const handleCanPlay = (event: Event) => {
  isLoading.value = false;
  emit('canplay', event);
};

const handlePlay = (event: Event) => {
  isPlaying.value = true;
  emit('play', event);
};

const handlePause = (event: Event) => {
  isPlaying.value = false;
  emit('pause', event);
};

const handleEnded = (event: Event) => {
  isPlaying.value = false;
  emit('ended', event);
};

const handleError = (event: Event) => {
  isLoading.value = false;
  hasError.value = true;
  const error = (event.target as HTMLVideoElement)?.error;

  switch (error?.code) {
    case 1:
      errorMessage.value = '视频下载被中断';
      break;
    case 2:
      errorMessage.value = '网络错误';
      break;
    case 3:
      errorMessage.value = '视频解码错误';
      break;
    case 4:
      errorMessage.value = '不支持的视频格式';
      break;
    default:
      errorMessage.value = props.errorText;
  }

  emit('error', event);
  console.error('Video error:', error);
};

const handleTimeUpdate = (event: Event) => {
  if (videoRef.value) {
    currentTime.value = videoRef.value.currentTime;
  }
  emit('timeupdate', event);
};

const handleVolumeChange = (event: Event) => {
  if (videoRef.value) {
    volume.value = videoRef.value.volume;
    isMuted.value = videoRef.value.muted;
  }
  emit('volumechange', event);
};

// 控制函数
const togglePlay = () => {
  if (videoRef.value) {
    if (isPlaying.value) {
      videoRef.value.pause();
    } else {
      videoRef.value.play();
    }
  }
};

const toggleMute = () => {
  if (videoRef.value) {
    videoRef.value.muted = !videoRef.value.muted;
  }
};

const setVolume = (event: Event) => {
  const target = event.target as HTMLInputElement;
  const newVolume = parseFloat(target.value) / 100;
  if (videoRef.value) {
    videoRef.value.volume = newVolume;
  }
};

const seekTo = (event: Event) => {
  const target = event.target as HTMLInputElement;
  const newTime = parseFloat(target.value);
  if (videoRef.value) {
    videoRef.value.currentTime = newTime;
  }
};

const toggleFullscreen = () => {
  if (videoRef.value) {
    if (document.fullscreenElement) {
      document.exitFullscreen();
    } else {
      videoRef.value.requestFullscreen();
    }
    emit('fullscreen', !document.fullscreenElement);
  }
};

const retry = () => {
  retryCount.value++;
  isLoading.value = true;
  hasError.value = false;
  emit('retry', retryCount.value);

  nextTick(() => {
    if (videoRef.value) {
      videoRef.value.load();
    }
  });
};

const formatTime = (seconds: number) => {
  if (isNaN(seconds)) return '00:00';
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
};

// 监听src变化，重新加载
watch(
  () => props.src,
  () => {
    isLoading.value = true;
    hasError.value = false;
    retryCount.value = 0;

    nextTick(() => {
      if (videoRef.value) {
        videoRef.value.load();
      }
    });
  }
);

// 支持HLS流媒体 (需要hls.js库)
const initHLS = async () => {
  if (props.streamType === 'hls' || (props.streamType === 'auto' && props.src.includes('.m3u8'))) {
    try {
      // 这里可以集成hls.js库
      console.log('HLS stream detected, would load hls.js here');
      // const Hls = await import('hls.js');
      // if (Hls.isSupported()) {
      //   const hls = new Hls();
      //   hls.loadSource(props.src);
      //   hls.attachMedia(videoRef.value);
      // }
    } catch (error) {
      console.warn('HLS.js not available, falling back to native video');
    }
  }
};

onMounted(() => {
  if (videoRef.value) {
    volume.value = videoRef.value.volume;
    isMuted.value = videoRef.value.muted;
  }
  initHLS();
});

onUnmounted(() => {
  // 清理资源
});

// 公开方法
defineExpose({
  play: () => videoRef.value?.play(),
  pause: () => videoRef.value?.pause(),
  seek: (time: number) => {
    if (videoRef.value) {
      videoRef.value.currentTime = time;
    }
  },
  setVolume: (vol: number) => {
    if (videoRef.value) {
      videoRef.value.volume = Math.max(0, Math.min(1, vol));
    }
  },
  mute: () => {
    if (videoRef.value) {
      videoRef.value.muted = true;
    }
  },
  unmute: () => {
    if (videoRef.value) {
      videoRef.value.muted = false;
    }
  },
  getCurrentTime: () => videoRef.value?.currentTime || 0,
  getDuration: () => videoRef.value?.duration || 0,
  getVideoElement: () => videoRef.value
});
</script>

<style scoped>
.video-loading,
.video-error {
  gap: 12px;
}

.loading-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #409eff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

.loading-text,
.error-message {
  color: #666;
  font-size: 14px;
}

.error-icon {
  font-size: 48px;
}

.error-message {
  max-width: 300px;
  line-height: 1.5;
  text-align: center;
}

.retry-button {
  background-color: #409eff;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.retry-button:hover {
  background-color: #337ecc;
}

.custom-controls {
  color: white;
}

.control-btn {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  color: white;
  padding: 5px 10px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 16px;
}

.control-btn:hover {
  background: rgba(255, 255, 255, 0.3);
}

.time-display {
  font-size: 12px;
  min-width: 80px;
}

.progress-bar,
.volume-bar {
  accent-color: #409eff;
}

.progress-bar {
  flex: 1;
  height: 4px;
}

.volume-bar {
  width: 60px;
  height: 4px;
}

.play-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 48px;
  cursor: pointer;
  opacity: 0.8;
  transition: opacity 0.3s;
}

.play-indicator:hover {
  opacity: 1;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .custom-controls {
    padding: 5px;
    gap: 5px;
  }

  .control-btn {
    padding: 3px 6px;
    font-size: 14px;
  }

  .time-display {
    font-size: 10px;
    min-width: 60px;
  }

  .volume-bar {
    width: 40px;
  }
}
</style>
